﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing.Design;
using System.Linq;

namespace Marmat.Forms.Views
{
    namespace DataGrid
    {
        [Editor("Marmat.Forms.Design.DataGridUITypeEditor", typeof(UITypeEditor))]
        public class ColumnCollection : IList, IList<Column>
        {
            private readonly Forms.DataGrid bDataGrid;
            private readonly Grid.ColumnCollection collection;

            internal ColumnCollection()
            {
            }

            internal ColumnCollection(Forms.DataGrid bDataGrid, Grid.ColumnCollection collection)
            {
                this.bDataGrid = bDataGrid;
                this.collection = collection;
            }

            void ICollection<Column>.CopyTo(Column[] array, int index)
            {
                ICollection<Grid.Column> collection = this.collection;
                collection.CopyTo(array, index);
            }

            void ICollection.CopyTo(Array array, int index)
            {
                Column[] columns = (Column[])array;
                ICollection<Grid.Column> collection = this.collection;
                collection.CopyTo(columns, index);
            }

            public int Count => this.collection.Count;

            public bool IsSynchronized => false;

            public object SyncRoot
            {
                get
                {
                    return this.collection;
                }
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return this.GetEnumerator();
            }

            public IEnumerator<Column> GetEnumerator()
            {
                ICollection<Grid.Column> collection = this.collection;
                return collection.OfType<Column>().GetEnumerator();
            }

            public Column Add(string ColumnName)
            {
                var Item = new Column();
                Item.Name = ColumnName;
                this.Add(Item);
                return Item;
            }

            public Column Add(string ColumnName, Type type)
            {
                var Item = new Column();
                Item.Name = ColumnName;
                Item.DataType = type;
                this.Add(Item);
                return Item;
            }

            public Column Add(string ColumnName, Type type, string expression)
            {
                var Item = new Column();
                Item.Name = ColumnName;
                Item.DataType = type;
                Item.Expression = expression;
                this.Add(Item);
                return Item;
            }

            public void Add(Column column)
            {
                if (column.DataType is null)
                {
                    column.DataType = typeof(string);
                }

                var DataColumn = new DataColumn();
                column.DataColumn = DataColumn;
                DataColumn.ColumnName = column.FieldName;
                DataColumn.DataType = column.DataType;
                DataColumn.Expression = column.Expression;
                DataColumn.AutoIncrement = column.AutoIncrement;
                if (ReferenceEquals(DataColumn.DataType, typeof(string)))
                {
                    DataColumn.MaxLength = column.MaxLength;
                }

                this.bDataGrid.DataSource.Columns.Add(DataColumn);
                if (column.DataType == typeof(bool))
                {
                    column.DataColumn.DefaultValue = false;
                }

                column.GridColumn.VisibleIndex = this.Count;
                column.GridColumn.FieldName = column.FieldName;
                IList list = this;
                list.Add(column);
            }

            int IList.Add(object value)
            {
                IList list = this.collection;
                return list.Add(value);
            }

            public void Clear()
            {
                this.bDataGrid.DataSource.Columns.Clear();
                this.bDataGrid.BaseGridView.Columns.Clear();
                this.collection.Clear();
            }

            public bool Contains(string ColumnName)
            {
                foreach (Column Item in this)
                {
                    if ((Item.Name ?? "") == (ColumnName ?? ""))
                    {
                        return true;
                    }
                }

                return false;
            }

            public bool Contains(Column item)
            {
                return this.collection.Contains(item);
            }

            bool IList.Contains(object value)
            {
                Column item = (Column)value;
                return this.Contains(item);
            }

            public int IndexOf(Column item)
            {
                return this.collection.IndexOf(item);
            }

            int IList.IndexOf(object value)
            {
                return this.IndexOf((Column)value);
            }

            public void Insert(int index, Column item)
            {
                this.bDataGrid.DataSource.Columns.Add(item.DataColumn);
                this.collection.Insert(index, item);
            }

            void IList.Insert(int index, object value)
            {
                Column item = (Column)value;
                this.Insert(index, item);
            }

            public bool IsFixedSize
            {
                get
                {
                    return false;
                }
            }

            public bool IsReadOnly
            {
                get
                {
                    return false;
                }
            }

            public new Column this[int index]
            {
                get
                {
                    return (Column)this.collection[index];
                }

                set
                {
                    throw new NotImplementedException();
                }
            }

            object IList.this[int index]
            {
                get => this.collection[index];
                set => throw new NotImplementedException();
            }

            public Column this[string colName]
            {
                get
                {
                    foreach (Column dc in this.bDataGrid.Columns)
                    {
                        if ((dc.Name ?? "") == (colName ?? ""))
                            return dc;
                    }
                    return null;
                }
            }

            public bool Remove(Column item)
            {
                if (this.Contains(item))
                {
                    this.bDataGrid.DataSource.Columns.Remove(item.DataColumn);
                    this.collection.Remove(item);
                    return true;
                }
                else
                {
                    return false;
                }
            }

            void IList.Remove(object value)
            {
                this.Remove((Column)value);
            }

            public void RemoveAt(int index)
            {
                this.collection.RemoveAt(index);
            }
        }
    }
}